#pragma once
#include <thread>
#include <iostream>
#include <functional>

template <class T>
using func_t = std::function<void(T)>; // 包装器

template <class T>
class Thread
{
public:
    Thread(const std::string &threadname, func_t<T> func, T data)
        : _tid(0), _threadname(threadname), _isrunning(false), _func(func), _data(data)
    {
    }

    static void *ThreadRoutine(void *args)
    {
        Thread *ts = (Thread *)args;
        ts->_func(ts->_data);
        return nullptr;
    }

    bool Start() // 启动线程
    {
        int n = pthread_create(&_tid, nullptr, ThreadRoutine, this);
        if (n == 0)
        {
            _isrunning = true;
            return true;
        }
        return false;
    }

    bool Join() // 回收线程
    {
        if (!_isrunning)
            return true;
        int n = pthread_join(_tid, nullptr); // 返回值为0，说明已经等待成功了
        if (n == 0)
        {
            _isrunning = false;
            return true;
        }
        return false;
    }

    std::string &GetThreadName()
    {
        return _threadname;
    }

    bool Isrunning()
    {
        return _isrunning;
    }

private:
    pthread_t _tid;
    std::string _threadname;
    bool _isrunning;
    func_t<T> _func;
    T _data;
};
